#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include "cbb_camera_process.h"
#include "cbb_camera_ctrl.h"

//设备列表
static CameraDev_t s_camera_dev_list[]  = {

};

//设备操作函数映射表
static CbbCameraCtrlFunMap_t s_camera_ctrl_fun_list[] = {
    {CBB_CAMERA_ACT_QUE_FMT, CbbCameraQuePixelFormat},
    {CBB_CAMERA_ACT_QUE_ALL, CbbCameraQueAllInfo},
    {CBB_CAMERA_ACT_SET_CONF, CbbCameraSetConf},
    {CBB_CAMERA_ACT_CTL_CAP, CbbCameraCtrlFlow},
};

CameraHandle CbbCameraOpen(const char *video_node)
{   
    if (NULL == video_node)  {
        printf("invaild params\r\n");
        return NULL;
    }
    CbbCameraHandle_t *p_camera_handle = NULL;
    p_camera_handle = calloc(1, sizeof(CbbCameraHandle_t));
    if (p_camera_handle == NULL) {
        printf("calloc p_camera_handle failed\r\n");
        return NULL;
    }
    
    //打开摄像头
    p_camera_handle->fd = open(video_node, O_RDWR | O_NONBLOCK);//| O_NONBLOCK
    if (p_camera_handle->fd < 0) {
        printf("open dev(%s) failed.\r\n", video_node);
        return NULL;
    }
    
    return p_camera_handle;
}

CbbCameraAckE_t CbbCameraCtrl(CameraHandle handle, const CbbCameraActionE_t action, CbbCameraCtrlDev_t *operate_p)
{
    if (NULL == handle || NULL == operate_p) {
        printf("invaild params\r\n");
        return CBB_CAMERA_ACK_ERROR;
    }

	for( size_t i = 0; i < CBB_ARRLEN(s_camera_ctrl_fun_list); i++) {
        if (action == s_camera_ctrl_fun_list[i].action) {
            return s_camera_ctrl_fun_list[i].CameraCtrl_pfun(handle, operate_p);
        }
    }

    return CBB_CAMERA_ACK_ERROR;
}

CbbCameraAckE_t CbbCameraReadFrame(CameraHandle handle, CbbCameraFrame_t *frame, hd_u16_t timeout_ms)
{
    if (NULL == handle || NULL == frame) {
        printf("invaild params\r\n");
        return CBB_CAMERA_ACK_ERROR;
    }
	printf("CbbCameraReadFrame in...\r\n");

    return CbbReadFrameData(handle, frame, timeout_ms);
}


CbbCameraAckE_t CbbCameraRestFrame(CameraHandle handle, CbbCameraFrame_t frame)
{
    if (NULL == handle) 
    {
        printf("invaild params\r\n");
        return CBB_CAMERA_ACK_ERROR;
    }

    CbbCameraHandle_t *camera_dev = (CbbCameraHandle_t *)handle;
    
    //判断帧缓冲区索引有效性
    if (frame.index < 0) {
        printf("frame.index error\r\n");
        return CBB_CAMERA_ACK_ERROR;
    }

    //先释放帧数据
    if (frame.data_addr){
        free(frame.data_addr);
    }
    
    return CbbResetBuffer(handle, frame, frame.index);
}


CbbCameraAckE_t CbbCameraClose(CameraHandle handle)
{   
    if (NULL == handle) {
        printf("invaild params\r\n");
        return CBB_CAMERA_ACK_ERROR;
    }

    CbbCameraHandle_t *camera_dev = (CbbCameraHandle_t *)handle;
    
    //停止视频流
    CbbStopCapture(handle);
    //关闭fd
    if (NULL != camera_dev) {
        if (camera_dev->fd >= 0) {
            close(camera_dev->fd);
        }
        free(camera_dev);
        camera_dev = NULL;
    }

    return CBB_CAMERA_ACK_OK;
}


void CbbCameraVersioin(CbbVersion_t *version_p)
{

}